﻿using System.Collections.Generic;
using System.Reflection;
using Collab.Common;
using Collab.Services.Remote.Contracts;
using Collab.Services.Remote.Entities;
using System.Diagnostics;

namespace Collab.Services.Remote
{
    public class RemoteCollaborationServiceProxy : ExceptionHandlingDuplexProxyBase<IRemoteCollaborationService, IRemoteCollaborationCallback>, IRemoteCollaborationService, ICommonRemoteMessages
    {
        private User user;
        public RemoteCollaborationServiceProxy(User user)
        {
            this.Subscribe(user);
        }

        public RemoteCollaborationServiceProxy(User user, IRemoteCollaborationCallback callbackObject) :
            base(callbackObject)
        {
            this.Subscribe(user);
        }

        public RemoteCollaborationServiceProxy(User user, IRemoteCollaborationCallback callbackObject, string endpointConfigurationName) :
            base(callbackObject, endpointConfigurationName)
        {
            this.Subscribe(user);
        }

        public RemoteCollaborationServiceProxy(User user, IRemoteCollaborationCallback callbackObject, string endpointConfigurationName, string remoteAddress) :
            base(callbackObject, endpointConfigurationName, remoteAddress)
        {
            this.Subscribe(user);
        }

        public RemoteCollaborationServiceProxy(User user, IRemoteCollaborationCallback callbackObject, System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
            base(callbackObject, binding, remoteAddress)
        {
            this.Subscribe(user);
        }
     
        protected override void Cleanup()
        {
            this.Unsubscribe(this.user);
            base.Cleanup();
        }

        #region IRemoteCollaborationService Members

        public void Subscribe(User user)
        {
            this.user = user;
            base.Invoke(MethodBase.GetCurrentMethod().Name, user);
        }

        public DocumentSnapshot GetCurrentRevision(string documentName)
        {
            return base.Invoke<DocumentSnapshot>(MethodBase.GetCurrentMethod().Name, documentName);
        }

        public IList<User> GetCurrentUsers()
        {
            return base.Invoke<IList<User>>(MethodBase.GetCurrentMethod().Name);
        }

        public Solution GetSolutionInformation()
        {
            return base.Invoke<Solution>(MethodBase.GetCurrentMethod().Name);
        }

        public void Unsubscribe(User user)
        {
            base.Invoke(MethodBase.GetCurrentMethod().Name, user);
        }

        public void SendChange(Entities.BufferUpdate change)
        {
            Debug.WriteLine("Sending change:" + change.UpdateIndex + ":" + change.Revision);
            base.Invoke(MethodBase.GetCurrentMethod().Name, change);
        }
        
        public void RequestFile(FileRequest fileRequest)
        {
            base.Invoke(MethodBase.GetCurrentMethod().Name, fileRequest);
        }

        #endregion


        public void SendUserStatus(UserStatus status)
        {
            base.Invoke(MethodBase.GetCurrentMethod().Name, status);
        }


        public void SendFileAdded(AddedFileInformation fileInformation)
        {
            base.Invoke(MethodBase.GetCurrentMethod().Name, fileInformation);
        }


        public void SendFileChunk(FileChunk fileChunk)
        {
            base.Invoke(MethodBase.GetCurrentMethod().Name, fileChunk);
        }

        public void PublishChange(BufferUpdate change)
        {
            SendChange(change);
        }

        public void PublishUserStatus(UserStatus status)
        {
            SendUserStatus(status);
        }

        public void PublishFileChunk(FileChunk fileChunk)
        {
            SendFileChunk(fileChunk);
        }

        public void PublishFileAdded(AddedFileInformation fileInformation)
        {
            SendFileAdded(fileInformation);
        }

        public void PublishFileRequested(FileRequest request, System.Guid userId)
        {
            RequestFile(request);
        }
    }
}
